package hu.bme.aut.consulttime.server.entityservices;

import hu.bme.aut.consulttime.client.EvaluationService;
import hu.bme.aut.consulttime.entitydtos.EvaluationDTO;
import hu.bme.aut.consulttime.server.email.EmailProvider;
import hu.bme.aut.consulttime.server.entities.Evaluation;
import hu.bme.aut.consulttime.server.entities.ToDo;

import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.TypedQuery;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class EvaluationServiceImpl extends RemoteServiceServlet implements EvaluationService {

	private static final long serialVersionUID = -8380175373104018653L;

	public static final EntityManager entityManager() {
		return EntityManagerFactoryWrapper.get().createEntityManager();
	}
	
	@Override
	public long createEvaluation(EvaluationDTO evaluationDTO) {

		EntityManager em = entityManager();
		EntityTransaction tx = em.getTransaction();

		Evaluation evaluation = new Evaluation();
		evaluation.setDate(evaluationDTO.getDate());
		evaluation.setDescription(evaluationDTO.getDescription());

		try {
			tx.begin();
			evaluation.setToDo(em.find(ToDo.class, evaluationDTO.getToDoId()));
			em.persist(evaluation);
			tx.commit();
		} 
		catch (Throwable t) {
			t.printStackTrace();
			tx.rollback();
		} 
		finally {
			em.close();
		}
		
		try {
			
			if (evaluation.getToDo().getStudent().isEmailNotification()) {
				
				String emailAddress = evaluation.getToDo().getStudent().getEmail();
				String subject = "New evaluation on ConsultTime!";
				String body = "Tutor: " + evaluation.getToDo().getTutor().getFirstName() + " " + evaluation.getToDo().getTutor().getLastName() + " (" + evaluation.getToDo().getTutor().getUserName() + ")\n";
				body = body + "Project: " + evaluation.getToDo().getTeam().getProject().getTitle() + "\n";
				body = body + "Team: " + evaluation.getToDo().getTeam().getName() + "\n";
				body = body + "Student: " + evaluation.getToDo().getStudent().getFirstName() + " " + evaluation.getToDo().getStudent().getLastName() + " (" + evaluation.getToDo().getStudent().getUserName() + ")\n\n";
				body = body + "To-do:\n";
				body = body + "Date: " + evaluation.getToDo().getDate().toString() + "\n";
				body = body + "Title: " + evaluation.getToDo().getTitle() + "\n";
				body = body + "Week: " + String.valueOf(evaluation.getToDo().getWeek()) + "\n\n";
				body = body + "Evaluation:\n";
				body = body + "Date: " + evaluation.getDate().toString() + "\n\n";
				body = body + evaluation.getDescription();
				
				EmailProvider.sendEmail(emailAddress, subject, body);
			}
		} catch (Throwable t) {
			t.printStackTrace();
		}
		
		return evaluationDTO.getToDoId();
	}
	
	@Override
	public EvaluationDTO retrieveEvaluation(long toDoId) {

		EntityManager em = entityManager();
		Evaluation evaluation = null;

		try {
			
			ToDo toDo = em.find(ToDo.class, toDoId);
			
			TypedQuery<Evaluation> query = em.createQuery("select e from Evaluation e where e.toDo = ?1", Evaluation.class);
			query.setParameter(1, toDo);
			evaluation = query.getSingleResult();
		}
		catch (Throwable t) {
			t.printStackTrace();
		}
		finally {
			em.close();
		}
		
		if (evaluation == null) {
			return new EvaluationDTO(toDoId);
		}
			
		return createEvaluationDTO(evaluation);
	}    
	
	@Override
	public long updateEvaluation(EvaluationDTO evaluationDTO) {

		EntityManager em = entityManager();
		EntityTransaction tx = em.getTransaction();
		
		Evaluation evaluation = new Evaluation();
		evaluation.setEvaluationId(evaluationDTO.getEvaluationId());
		evaluation.setDate(evaluationDTO.getDate());
		evaluation.setDescription(evaluationDTO.getDescription());

		try {
			tx.begin();
			evaluation.setToDo(em.find(ToDo.class, evaluationDTO.getToDoId()));
			em.merge(evaluation);
			tx.commit();
		} 
		catch (Throwable t) {
			t.printStackTrace();
			tx.rollback();
		} 
		finally {
			em.close();
		}
		
		try {
			
			if (evaluation.getToDo().getStudent().isEmailNotification()) {
				
				String emailAddress = evaluation.getToDo().getStudent().getEmail();
				String subject = "Updated evaluation on ConsultTime!";
				String body = "Tutor: " + evaluation.getToDo().getTutor().getFirstName() + " " + evaluation.getToDo().getTutor().getLastName() + " (" + evaluation.getToDo().getTutor().getUserName() + ")\n";
				body = body + "Project: " + evaluation.getToDo().getTeam().getProject().getTitle() + "\n";
				body = body + "Team: " + evaluation.getToDo().getTeam().getName() + "\n";
				body = body + "Student: " + evaluation.getToDo().getStudent().getFirstName() + " " + evaluation.getToDo().getStudent().getLastName() + " (" + evaluation.getToDo().getStudent().getUserName() + ")\n\n";
				body = body + "To-do:\n";
				body = body + "Date: " + evaluation.getToDo().getDate().toString() + "\n";
				body = body + "Title: " + evaluation.getToDo().getTitle() + "\n";
				body = body + "Week: " + String.valueOf(evaluation.getToDo().getWeek()) + "\n\n";
				body = body + "Evaluation:\n";
				body = body + "Date: " + evaluation.getDate().toString() + "\n\n";
				body = body + evaluation.getDescription();
				
				EmailProvider.sendEmail(emailAddress, subject, body);
			}
		} catch (Throwable t) {
			t.printStackTrace();
		}
		
		return evaluationDTO.getToDoId();

	}
	
	@Override
	public long deleteEvaluation(long evaluationId) {

		EntityManager em = entityManager();
		EntityTransaction tx = em.getTransaction();
		long toDoId = 0;

		try {
			tx.begin();
			Evaluation evaluation = em.find(Evaluation.class, evaluationId);
			toDoId = evaluation.getToDo().getTodoId();
			em.remove(evaluation);
			tx.commit();
		} 
		catch (Throwable t) {
			t.printStackTrace();
			tx.rollback();
		} 
		finally {
			em.close();
		}
		
		return toDoId;
	}

	private EvaluationDTO createEvaluationDTO(Evaluation evaluation) {
			return new EvaluationDTO(evaluation.getEvaluationId(), evaluation.getDate(), evaluation.getDescription(), evaluation.getToDo().getTodoId());
	}
}
